<?php
  // no direct access
  defined( '_JEXEC' ) or die( 'Restricted access' );
  jimport('joomla.application.component.controller');
  
  class SchedulesController extends JController
  {  
    function display(){
      
      $document =& JFactory::getDocument();
      $view = & $this->getView($this->_name, $document->getType());
      
      $mseason     = $this->getModel('season', 'seasonmodel');
      $mdivision     = $this->getModel('division', 'divisionmodel');
      
      $season      = $mseason->get_latest();
      $weeks       = $this->get_weeks($season);
      $week_number = JRequest::getVar('id');
      
	  if(!empty($weeks)){
        if(!$week_number && $week_number!='0')
          $week_number = $this->get_current_week($weeks);
      
        $schedules       = $this->prepare_schedules($weeks[$week_number]->start, $weeks[$week_number]->end);
        $bye_teams       = $this->prepare_byes($weeks[$week_number]->start, $weeks[$week_number]->end);
      
        $view->assign("bye_teams", $bye_teams);
        $view->assign("weeks", $weeks);
        $view->assign("schedules", $schedules);
        $view->assign("current_week", $week_number);
      }
	  
      $view->assign("divisions", $mdivision->get());
      $view->display();
    }
    
    function display_schedule(){
    
      $document =& JFactory::getDocument();
      $view = & $this->getView($this->_name, $document->getType());
      
      $mseason     = $this->getModel('season', 'seasonmodel');
      $mschedule       = $this->getModel('schedule', 'schedulemodel'); 
      $mplayer         = $this->getModel('player', 'playermodel');
      $mpgs            = $this->getModel('playergamestat', 'playergamestatmodel');
      $mpic         = $this->getModel('pic', 'picmodel');
      
      $season          = $mseason->get_latest();
      $weeks          = $this->get_weeks($season);
      $week_number     = $this->get_current_week($weeks);
      
      $schedule_id     = JRequest::getVar('id');
      $schedule        = $mschedule->get($schedule_id);
      $this->prepare_schedule($schedule);
      
      $players         = array();
      foreach(array($schedule->first_team_id, $schedule->second_team_id) as $team_id){
        $tmp_players     = $mplayer->get_by_team_id($team_id);
        if(!empty($tmp_players))
          $players[$team_id] = $this->prepare_players($tmp_players);
      }

      $pgs    = $mpgs->get_by_schedule_id($schedule_id);
      if($pgs){
        $view->assign("stats", $this->prepare_stats($pgs));
        $view->assign("player_of_the_game", $this->prepare_potg($schedule));
        
        # graph
        $team_stats = $this->prepare_team_stats($pgs);
        $graph      = $this->create_stats_graph($schedule, $team_stats);
        $view->assign("graph", $graph);
      }
      
      $view->assign("players", $players);
      $view->assign("schedule", $schedule);
      $view->assign("weeks", $weeks);
      $view->assign("current_week", $week_number);
      $view->display('schedule');
      
    }
    
    /* returns the weeks within the season indexed from 0.... */
    private function get_weeks($season){
      
      $result = array();
      if(!$season)
        return $result;
      
      $start  = strtotime($season->start_date);
      $end    = strtotime($season->end_date);
      $sec_wk = 60*60*24*7;
      $weeks  = floor(($end - $start)/$sec_wk);
      
      for($i = 0; $i < $weeks; $i++){
        $result[$i] = new stdClass();
        $result[$i]->start = strftime('%Y-%m-%d', $start + ($i * $sec_wk));
        $result[$i]->end   = strftime('%Y-%m-%d', $start + (($i + 1) * $sec_wk));
      }
      
      return $result;
    }
    
    /* returns the current week number*/
    private function get_current_week($weeks){
      
      $result = 0;
      $now    = time();
      foreach($weeks as $index => $week){
        $start = strtotime($week->start);
        $end   = strtotime($week->end);
        if($start <= $now && $end >= $now)
          return $index;
      }
      return $result;
    }

    /* prepares schedules of games per week */
    private function prepare_schedules($start_date, $end_date){
      
      $result    = array();
      $schedule  = $this->getModel('schedule', 'schedulemodel');
      
      $schedules = $schedule->get_by_schedule($start_date, $end_date);
      if($schedules){
        foreach($schedules as $schedule){
          
          $this->prepare_schedule($schedule);
          array_push($result, $schedule);
        }
      }
      
      return $result;
    }
    
    private function prepare_byes($start_date, $end_date){
    
      $bye      = $this->getModel('bye', 'byemodel');
      $byeteam  = $this->getModel('byeteam', 'byeteammodel');
      $team     = $this->getModel('team', 'teammodel');
      
      $byes = $bye->get_by($start_date, $end_date);
	  $result = array();
	  if($byes){
	    foreach($byes as $b){
          $bts = $byeteam->get_by($b->id);
          foreach($bts as $bt)
            array_push($result, $team->get($bt->team_id));
        }
	  }
      
      return $result;
    }
    
    private function prepare_schedule(&$schedule){
    
      $team      = $this->getModel('team', 'teammodel');
      $venue     = $this->getModel('venue', 'venuemodel');
      $gs        = $this->getModel('gamestat', 'gamestatmodel');
	  $ges       = $this->getModel('gameendstatus', 'gameendstatusmodel');
      
      /* schedule_id, date, time, venue, team1, team2, final score */
      $schedule->venue       = $venue->get($schedule->venue_id, false, array('name'));
      $schedule->first_team  = $team->get($schedule->first_team_id, false, array('id', 'name', 'abbr'));
      $schedule->second_team = $team->get($schedule->second_team_id, false, array('id', 'name', 'abbr'));
      $schedule->division    = $this->get_division($schedule);
    
      $schedule->final_score = array($schedule->first_team_id => 0, $schedule->second_team_id => 0);
      $stats = $gs->get_by($schedule->id);
	  
      if($stats){
	    foreach($stats as $stat){
	      $schedule->game_end_status = $ges->get($stat->game_end_status_id);
	      $schedule->final_score[$schedule->first_team_id]  = $stat->first_team_final_score;
          $schedule->final_score[$schedule->second_team_id] = $stat->second_team_final_score;
		}
      }
      
    }
    
    private function get_division($schedule){
      $division  = $this->getModel('division', 'divisionmodel');
      
      # get division for the schedule
      $division_result = array();
      foreach(array($schedule->first_team_id, $schedule->second_team_id) as $tid){
        
        $divisions = $division->get_by_team_id($tid);
        $division_result[$tid] = array();
        
        foreach($divisions as $d)
          array_push($division_result[$tid], $d->id);
      }
      $divisions = array_intersect($division_result[$schedule->first_team_id],
                                   $division_result[$schedule->second_team_id]);

      if(!empty($divisions))
        return $division->get($divisions[0]);
    }
  
    private function prepare_players($players){
    
      $result = array();
      $person = $this->getModel('person', 'personmodel');
      
      foreach($players as $player)
        $result[$player->id] = $person->get_fullname($player->person_id);
      
      return $result;
    }
  
      private function prepare_team_stats($pgs){
    
      $result = array();
      $mteam     = $this->getModel('team', 'teammodel');
      $mplayer   = $this->getModel('player', 'playermodel');
      
      foreach($pgs as $p){
        $player = $mplayer->get($p->player_id);
        
        if(!isset($result[$player->team_id])){
          $team = $mteam->get($player->team_id, false,array('id', 'name', 'abbr'));
          $result[$player->team_id] = (object)array('field_goals' => 0,
                                                    'free_throws' => 0,
                                    'three_points'=> 0,
                                    'team' => $team);
          }
        $result[$player->team_id]->field_goals  += $p->field_goals;
        $result[$player->team_id]->three_points += $p->three_points;
        $result[$player->team_id]->free_throws  += $p->free_throws;        
      }

      return $result;
    }
  
    private function prepare_stats($stats){
      
      $result = array();
      foreach($stats as $stat)
        $result[$stat->player_id] = $stat;
      
      return $result;
    }
    
    private function prepare_potg($schedule){
      
      $mplayer   = $this->getModel('player', 'playermodel');
      $mperson   = $this->getModel('person', 'personmodel');
      $mpic      = $this->getModel('pic', 'picmodel');
      $mpgs      = $this->getModel('playergamestat', 'playergamestatmodel');
      $mgs       = $this->getModel('gamestat', 'gamestatmodel');
      
      $gs     = $mgs->get_by($schedule->id, null, null, 1);
      if(!empty($gs)){
        foreach($gs as $g){
          if($g->first_team_final_score > $g->second_team_final_score)
            $winner_team_id = $schedule->first_team_id;
          else
            $winner_team_id = $schedule->second_team_id;
        }
        
        $pgs    = $mpgs->get_by_schedule_id($schedule->id, $winner_team_id);
        if($pgs){
          foreach(array('points', 'rebounds', 'assists', 'steals', 'blocks') as $category){
            $temp_result = null;
            if($category == 'rebounds')
              $temp_result = $this->custom_players_sort($pgs, array('def_rebounds', 'off_rebounds'));
            else
              $temp_result = $this->custom_players_sort($pgs, $category);
            
            if(!$this->array_top_unique($temp_result)){
              //shorten pgs
              $pgs = $this->collect_highest($pgs, $category);
              continue;
            }
            else{
              $potg_id = array_shift(array_keys($temp_result));
              $potg    = $mplayer->get($potg_id);
              $potg->person = $mperson->get($potg->person_id);
              $potg->pic    = $mpic->get($potg->pic_id);
              return $potg;
            }
          }
        }
      }
      
      return null;
    }
    
    private function custom_players_sort($a,$subkey) {
    
      if(empty($a))
        return array();
        
      foreach($a as $k=>$v){
        if(is_array($subkey)){
          $value = null;
          foreach($subkey as $sk)
            $value = $value + $v->$sk;
            
          $b[$v->player_id] = $value;
        }
        else
          $b[$v->player_id] = $v->$subkey;
      }
      arsort($b);
    
      return $b;
    }
    
    private function array_top_unique($a){
    
      $result = true;
      foreach($a as $k => $v){
        if(!isset($init)){
          $init = $v;
          continue;
        }
        if($init == $v)
          return false;
      }
      return $result;
    }
    
    private function collect_highest($pgs, $category){
      
      $result = Array();
      foreach($pgs as $p){
      
        $points = $p->$category;
        if(!isset($result[$points]))
          $result[$points] = Array();
        
        array_push($result[$points], $p);
      }
      krsort($result);
      return array_shift($result);
    }
  
    /* returns path to image generated */
    private function create_stats_graph($schedule, $stats){
    
      require_once JPATH_COMPONENT.DS.'pChart'.DS.'pChart'.DS.'pData.php';
      require_once JPATH_COMPONENT.DS.'pChart'.DS.'pChart'.DS.'pChart.php';
      
      #if graph exists
      $schedule_id = $schedule->id;
      $result = "images/uploads/gs_graph$schedule_id.jpg";
      $actual_filepath = JPATH_BASE.DS.'images'.DS.'uploads'.DS."gs_graph$schedule_id.jpg";
      
      #if(file_exists($actual_filepath) && (time()-filemtime($actual_filepath))<300)
      #  return $result;
      $font   = JPATH_COMPONENT.DS.'pChart'.DS.'Fonts'.DS.'tahoma.ttf';  #tahoma.ttf
	  
      $dataRow = Array();
      foreach($stats as $stat){
        
        $raw = Array(
          'FG' => $stat->field_goals,
          'FT' => $stat->free_throws,
          'TP' => $stat->three_points,
          'team' => $stat->team->id,
          'name' => $stat->team->abbr
        );  
        
        array_push($dataRow, $raw);
      }
      
      // Dataset definition  
      $DataSet = new pData;
      foreach($dataRow as $i => $row){
        $DataSet->AddPoint($row['FG'], $row['team']);
        $DataSet->AddPoint($row['FT'], $row['team']);
        $DataSet->AddPoint($row['TP'], $row['team']);
        $DataSet->SetSerieName($row['name'], $row['team']);
      }
      
      $DataSet->AddPoint(array("FG","FT","TP"),"Names"); 
      $DataSet->AddAllSeries();  
      $DataSet->RemoveSerie("Names");  
        $DataSet->SetAbsciseLabelSerie("Names");
        
       // Initialise the graph  
      $Test = new pChart(200, 380);  
      $Test->setFontProperties($font,9);
	  $Test->setGraphArea(50,20,180,330);  
      $Test->drawFilledRoundedRectangle(7,7,200,380,5,240,240,240);  
      $Test->drawRoundedRectangle(5,5,695,265,5,270,270,270);  
      $Test->drawGraphArea(255,255,255,TRUE);  
      $Test->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_NORMAL,150,150,150,TRUE,0,2,TRUE);  
      $Test->drawGrid(4,TRUE,230,230,230,50);  
         
      // Draw the 0 line  
      $Test->setFontProperties($font,6);  
      $Test->drawTreshold(0,143,55,72,TRUE,TRUE);  
      
      // Draw the bar graph
      $Test->setColorPalette(0,200,0,0);
      $Test->setColorPalette(1,0,0,200);
      $Test->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription());
      
      // Finish the graph  
      $Test->setFontProperties($font,7);  
      $Test->drawLegend(135,355,$DataSet->GetDataDescription(),255,255,255);
      $Test->setFontProperties($font,10);  
      $Test->Render($actual_filepath);  
      $Test->ReportWarnings();  
      
      return $result;
    }
  }
?>
